package com.lusang.gift.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.lusang.gift.domain.LoginUser;
import com.lusang.gift.exception.asserts.Assert;
import com.lusang.gift.exception.code.StatusCode;
import org.apache.logging.log4j.util.Strings;
import com.lusang.gift.clients.LoginUserClient;
import com.lusang.gift.domain.Employee;
import com.lusang.gift.domain.Tenant;
import com.lusang.gift.dto.TenantEnterDto;
import com.lusang.gift.mapper.EmployeeMapper;
import com.lusang.gift.mapper.TenantMapper;
import com.lusang.gift.query.TenantQuery;
import com.lusang.gift.service.ITenantService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.lusang.gift.util.AjaxResult;
import com.lusang.gift.util.PageList;
import com.lusang.gift.util.encrypt.MD5;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private LoginUserClient loginUserClient;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Override
    public PageList<Tenant> selectPageList(TenantQuery query) {
        //分页不需要自己写 它自己有封装，只需要传入分页条件
        Page<Object> page = new Page<>(query.getPage(), query.getRows());
        //做跨表查询
        List<Tenant> datas = tenantMapper.loadPageList(page,query);
        return new PageList<>(page.getTotal(),datas);
    }

//    @Override
//    @Transactional
//    public void tenantEnter(TenantEnterDto tenantEnterDto) {
//        //租户入驻
//        Employee admin = tenantEnterDto.getAdmin();//管理员
//        Tenant tenant = tenantEnterDto.getTenant();//租户信息
//        Long mealId = tenantEnterDto.getMealId();//套餐id
//
//        //null校验
//        if (tenantEnterDto == null) {
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        }
//        if (Strings.isEmpty(tenant.getCompanyName())) {//租户名
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        }
//        if (admin == null) {//管理员
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        }
//        //两次密码比对
//        if (admin.getComfirmPassword() == null|| admin.getPassword()==null
//                || !tenantEnterDto.getAdmin().getPassword().equals(tenantEnterDto.getAdmin().getComfirmPassword())) {
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        }
//        //租户是否存在
//        Tenant byName = tenantMapper.loadByName(tenant.getCompanyName());
//        if (byName != null) {
//            throw new RuntimeException("系统错误！该已经租户存在");
//        }
//        //盐值
//        String uuid = UUID.randomUUID().toString();
//        String salt = "lusang"+uuid;
//        //MD5加密
//        String passForMD5 = MD5.getMD5(admin.getPassword()+salt);
//        //保存loginUser
//        LoginUser loginUser = new LoginUser();
//        loginUser.setUsername(admin.getUsername());
//        loginUser.setPassword(passForMD5);
//        loginUser.setEmail(admin.getEmail());
//        loginUser.setTel(admin.getTel());
//        loginUser.setType(1);//1表示管理人员 0表示用户
//        loginUser.setSalt(salt);
//        AjaxResult ajaxResult = loginUserClient.saveUser(loginUser);
//        Object obj = ajaxResult.getResultObj();
//        //这里有个坑，Long存放进一个Object的内存中 比如AjaxResult 和map<Sstring,Object>中 再拿出来会降级成为Integer
//        Integer loginInteger = (Integer)obj;
//        Long loginId = loginInteger.longValue();
//        //获取loginUser的id 存入admin的loginId
//        admin.setLoginId(loginId);
//        admin.setInputTime(new Date());
//        admin.setState(0);
//
//        admin.setPassword(passForMD5);
//        //保存管理员信息 返回管理员id
//        employeeMapper.insert(admin);
//        Long adminId = admin.getId();
//        tenant.setRegisterTime(new Date());
//        tenant.setState(0);
//        tenant.setAdminId(adminId);
//
//        tenantMapper.insert(tenant);
//
//        //保存租户和套餐关联表
//        Long tenantId = tenant.getId();
//        Map<String,Object> map = new HashMap<>();
//        //设置过期时间 当前时间加1年
//        Calendar instance = Calendar.getInstance();
//        instance.setTime(new Date());
//        instance.add(Calendar.YEAR, 1);
//        Date expireDate = instance.getTime();//过期时间
//
//        map.put("tenantId", tenantId);
//        map.put("mealId",mealId);
//        map.put("expireDate", expireDate);
//        map.put("state",0);//状态,是否过期 0 未支付，1已经购买，2过期
//        tenantMapper.insertMeal(map);
//    }
    @Override
    @Transactional
    public AjaxResult settlement(TenantEnterDto tenantEnterDto) {
        Employee admin = tenantEnterDto.getAdmin();
        Tenant tenant = tenantEnterDto.getTenant();
        Long mealId = tenantEnterDto.getMealId();

        // 校验
        validate(tenantEnterDto);
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(admin, loginUser);
        loginUser.setType(0);//登录用户类型为管理员
        AjaxResult ajaxResult = loginUserClient.addOrUpdate(loginUser);
        if (!ajaxResult.isSuccess()){
            return AjaxResult.me().setSuccess(false).setMessage(ajaxResult.getMessage());
        }

        // 保存店铺管理员
        admin.setType(5);//机构管理员
        //这里登录用户返回的自增id在另一个模块，这里拿不到,所以登录用户id存到resultObj里面，
        //存的时候是Long,通过Object转换，拿出来就是Integer了
        Long loginId = Long.valueOf((ajaxResult.getResultObj().toString()));
        admin.setLoginId(loginId);
        employeeMapper.insert(admin);

        // 保存店铺
        tenant.setState(0);//待审核
        tenant.setAdminId(admin.getId());
        tenantMapper.insert(tenant);

        // 保存用户套餐中间表
        Long tenantId = tenant.getId();
        Map<String,Object> map = new HashMap<>();
        map.put("mealId",mealId);
        map.put("tenantId",tenantId);
        map.put("state", 0);//未支付
        tenantMapper.insertTenantMeal(map);

        return AjaxResult.me();
    }
    // 自定义异常
    /*
    private void validate(TenantEnterDto tenantEnterDto) {
        // 参数校验
        // null校验
        Employee admin = tenantEnterDto.getAdmin();
        Tenant tenant = tenantEnterDto.getTenant();
        Long mealId = tenantEnterDto.getMealId();
        //用户信息校验
        if(admin == null)
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        if(StringUtils.isEmpty(admin.getUsername()) || StringUtils.isEmpty(admin.getPassword()) || StringUtils.isEmpty(admin.getComfirmPassword()))
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        //两次密码比对
        if (!admin.getPassword().trim().equals(admin.getComfirmPassword().trim()))
            throw new BusinessException("两次密码不一致");
        //租户信息校验
        if(tenant == null)
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        if (StringUtils.isEmpty(tenant.getCompanyName()) || StringUtils.isEmpty(tenant.getAddress()))
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        //套餐校验
        if(mealId == null)
            throw new BusinessException("系统错误！请输入相关信息后再操作");


        // 店铺是否存在校验
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>()
                .eq("company_name", tenant.getCompanyName())
        );
        if (tenants != null && tenants.size()>0)
            throw new BusinessException("该店铺已经存在！");
        //1.3 管理员存在校验
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username",admin.getUsername()));
        if (employees != null && employees.size()>0)
            throw new BusinessException("请登录，在后台添加租户提交审核！");
    }*/

    // 断言版
    /*
    private void validate(TenantEnterDto tenantEnterDto) {
        // 参数校验
        // null校验
        Employee admin = tenantEnterDto.getAdmin();
        Tenant tenant = tenantEnterDto.getTenant();
        Long mealId = tenantEnterDto.getMealId();
        //用户信息校验
        Assert.assertNotNull(admin,"系统错误！请输入相关信息后再操作");
        Assert.assertNotEmpty(admin.getUsername(),"系统错误！请输入相关信息后再操作");
        Assert.assertNotEmpty(admin.getPassword(),"系统错误！请输入相关信息后再操作");
        Assert.assertNotEmpty(admin.getComfirmPassword(),"系统错误！请输入相关信息后再操作");

        //两次密码比对
        Assert.assertEquals(admin.getPassword(),admin.getComfirmPassword(),"两次密码不一致");
        //租户信息校验
        Assert.assertNotNull(tenant,"系统错误！请输入相关信息后再操作");
        Assert.assertNotEmpty(tenant.getAddress(),"系统错误！请输入相关信息后再操作");
        Assert.assertNotEmpty(tenant.getCompanyName(),"系统错误！请输入相关信息后再操作");
        //套餐校验
        Assert.assertNotNull(mealId,"系统错误！请输入相关信息后再操作");

        // 店铺是否存在校验
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>().eq("company_name", tenant.getCompanyName()));
        Assert.assertListIsEmpty(tenants,"该店铺已经存在！");
        // 管理员存在校验
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username",admin.getUsername()));
        Assert.assertListIsEmpty(employees,"请登录，在后台添加租户提交审核！");
    }*/

    private void validate(TenantEnterDto tenantEnterDto) {
        // 参数校验
        // null校验
        Employee admin = tenantEnterDto.getAdmin();
        Tenant tenant = tenantEnterDto.getTenant();
        //两次密码比对
        Assert.assertEquals(admin.getPassword(),admin.getComfirmPassword(),"两次密码不一致");
        // 店铺是否存在校验
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>().eq("company_name", tenant.getCompanyName()));
        Assert.assertListIsEmpty(tenants, StatusCode.CODE_400_TENANT_EXSIT);
        // 管理员存在校验
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username",admin.getUsername()));
        Assert.assertListIsEmpty(employees, StatusCode.CODE_400_TENANT_ADMIN_EXSIT);
    }
}
